﻿#pragma once

#include <cmath>
#include <list>
#include <vector>
#include "discrete_acis_utils.hxx"

/**
 * 离散化一个边
 * @param dt distance tolerance 距离容差
 * @param at angular tolerance 角度容差
 *
 * #define straight_type 1   // strdef.hxx
 * #define ellipse_type 2    // elldef.hxx 椭圆线
 * #define helix_type 4      // heldef.hxx 螺旋线
 * #define intcurve_type 11  // intdef.hxx
 */
outcome facet_edge(EDGE* e, double dt, double at, AF_POINT*& out_points, int& out_cnt);

/**
 * 离散一个圆弧边.
 * @param curve 给定的圆弧边
 * @param st 边的起始参数值
 * @param ed 边的终止参数值
 * @param dt 边的距离容差
 * @param at 边的角度容差
 * @param sense 边的朝向（0为正向，1为反向）
 * @param head 边的AF_POINT头节点
 */
void facet_edge_circle(const ellipse* curve, double st, double ed, double dt, double at, int sense, AF_POINT* head);

/**
 * 离散一个圆弧边.
 * @param curve 给定的椭圆线边
 * @param st 边的起始参数值
 * @param ed 边的终止参数值
 * @param dt 边的距离容差
 * @param at 边的角度容差
 * @param sense 边的朝向（0为正向，1为反向）
 * @param head 边的AF_POINT头节点
 */
void facet_edge_ellipse(const ellipse* curve, double st, double ed, double dt, double at, int sense, AF_POINT* head);

/**
 * 离散一个圆弧边.
 * @param curve 给定的螺旋线边
 * @param st 边的起始参数值
 * @param ed 边的终止参数值
 * @param dt 边的距离容差
 * @param at 边的角度容差
 * @param sense 边的朝向（0为正向，1为反向）
 * @param head 边的AF_POINT头节点
 */
void facet_edge_helix(const helix* curve, double st, double ed, double dt, double at, int sense, AF_POINT* head);

/**
 * 离散一个圆弧边.
 * @param curve 给定插值曲线边
 * @param st 边的起始参数值
 * @param ed 边的终止参数值
 * @param dt 边的距离容差
 * @param at 边的角度容差
 * @param sense 边的朝向（0为正向，1为反向）
 * @param head 边的AF_POINT头节点
 */
void facet_edge_intcurve(const intcurve* curve, double st, double ed, double dt, double at, int sense, AF_POINT* head);

/**
 * 二维三角形ABC与三角形ADE相似
 *         C
 *     E
 * A   D   B
 * 利用相似三角形求相似比例以及E的坐标y.
 * \param x E.x = D.x
 * \param prev_x A.x
 * \param adjusted_x C.x = B.x
 * \param prev_y  A.y
 * \param adjusted_y C.y
 * \param proportion AD / AB
 * \param val E.y
 */
void similar_triangle_intersection(double x, double prev_x, double adjusted_x, double prev_y, double adjusted_y, double& proportion, double& val);

/**
 * 用于检查边离散的各段是否与该EDGE所在的其他面的参数域边界相交.
 * @param e 边
 * @param head 边的AF_POINT头节点
 */
void CheckParamBoundary(EDGE* e, AF_POINT* head);

/**
 * 用于检查边离散的各段是否与该EDGE所在的其他面的参数域边界相交.(使用求交版本)
 * @param e 边
 * @param head 边的AF_POINT头节点
 */
void NewCheckParamBoundary(EDGE* e, AF_POINT* head);
/**
 * 辅助函数，用于判断曲线的某个参数区间是否满足距离容差.
 * @param e 边
 * @param dt 需要满足的边距离容差
 * @param head 边的AF_POINT头节点
 * @param end_pt 检查区间的终止节点
 */
void CheckDistanceTolerance(EDGE* e, double dt, double at, AF_POINT* head, AF_POINT* end_pt);

/**
 * 辅助函数，用于判断曲线的某个参数区间是否满足角度容差.
 * @param e 边
 * @param at 需要满足的边角度容差
 * @param head 边的AF_POINT头节点
 */
void CheckAngularTolerance(EDGE* e, double& at, AF_POINT* head);

/**
 * 辅助函数，用于将距相邻曲面的奇点较近的曲线分段进行加密处理
 * @param e 边
 * @param head 边离散结果的头节点
 * @param dt 距离容差
 */
void CheckSingularities(EDGE* e, AF_POINT* head, double dt, double at);

// @warning 此处判断采用了近似，可能会产生错误
inline bool same_point(double& p1, double& p2, const curve& c) {
    return c.eval_position(p1, TRUE, TRUE) == c.eval_position(p2, TRUE, TRUE);
}
